home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / PROGBLER / ASMCODE2.LZH / SQ_RT.ASM < prev    next >
Assembly Source File  |  1983-10-15  |  14KB  |  448 lines

  1. ;SQR_T.ASM          10-14-83
  2. ;
  3. ;PROGRAM TO TAKE KEYBOARD INPUT AND CALCULATE THE SQUARE
  4. ;ROOT USING THE SQ ROOT ROUTINE, THEN DISPLAY THE RESULT
  5. ;
  6. EXTRN ASCII_BIN:FAR    ;EXTERNAL SUBROUTINE
  7. EXTRN BIN_ASCII:FAR    ;EXTERNAL SUBROUTINE
  8. EXTRN DEC_ADJ:FAR      ;EXTERNAL SUBROUTINE
  9. EXTRN PUT_DEC:FAR
  10. ;---------------------------------------
  11. STACK SEGMENT PARA STACK 'STACK'
  12.       DB 256 DUP(0)
  13. STACK ENDS
  14. ;----------------------------------------
  15. DATA SEGMENT PARA 'DATA'
  16. ESC           EQU  27  ;ESC USED TO RETURN TO DOS
  17. END_SYM       EQU '\' ;SYMBOL AT END OF STRING
  18. SC_TITLE      DB  'INTEGER SQUARE ROOT ROUTINE\'
  19. TYPE_NUM      DB  'FOR A POSITIVE NUMBER FROM 0 TO 32767\'
  20. INPUT_NUM     DB  'INPUT TEST NUMBER \'
  21. COL_HEADER    DB  'TEST NUMBER            SQ ROOT\'
  22. UNDERLINE     DB  '-----------            --------\'
  23. ERR_MSG1      DB  'NOT VALID NUMBER - REDO \'
  24. ERR_MSG2      DB  'NUMBER TOO LARGE - REDO \'
  25. ERR_MSG3      DB  'NEGATIVE NUMBER - REDO\'
  26. BLANKS        DB  '                         \'  ;25 BLANKS
  27. TEST_STRING   DB  10 DUP(0)
  28. TEST_NUMBER   DW  0  ;THE TEST_STRING CONVERTED TO A NUMBER
  29. CHAR_COUNT    DW  0  ;NO. OF CHARS IN A STRING - CX IN BIOS CALL
  30. SQ_ROOT_VALUE   DW  0  ;CALUCLATED SQ ROOT VALUE
  31. SQ_ROOT_STRING  DB '          \' ;STRING TO PUT CAL VALUE IN FOR DISP
  32. OFFSET_VALUE  DW  0
  33. INPUT_LARGE   DW  0  ;STATUS PASSING INDICATOR
  34. INPUT_STATUS  DW  0  ;STATUS PASSING INDICATOR
  35. DEC_POINT     DW  0
  36. test1         db  'test4\'
  37. test2         db  'test2\'
  38. test3         db  'test3\'
  39. TEST_NUM_CNT  DB  10 DUP (0)   ;STRING TO USE IN FINDING WHERE DECIMAL WAS
  40. TEST_NUMBER_SIZE  DW  0        ;INDICATOR IF TEST_NUMBER <1 OR >1
  41. data ends
  42. ;----------------------------------------
  43. CODE  SEGMENT PARA PUBLIC 'CODE'
  44. START PROC FAR
  45. ;
  46. ;STANDARD PROGRAM PROLOGUE
  47. ;
  48.        ASSUME CS:CODE                  
  49.  
  50.        PUSH DS
  51.        MOV  AX,0
  52.        PUSH AX
  53.        MOV  AX,DATA
  54.        MOV  DS,AX
  55.        ASSUME DS:DATA
  56.  
  57.        CALL CLEAR_THE_SCREEN 
  58.  ;PUT STRING OF SCREEN
  59.  
  60. ;IF COLOR GRAPHICS MAKE SURE IS MODE 2
  61.         MOV  AH,15
  62.         INT  10H
  63.         CMP  AL,7           ;IS IT MONOCHROME?
  64.         JE  SCREEN_MODE_OK  ;YES
  65.         CMP  AL,2           ;NOT MONO, IS MODE 2?
  66.         JE  SCREEN_MODE_OK  ;YES
  67.         MOV  AH,0           ;NOT MODE 2 SO MAKE IT
  68.         MOV  AL,2           ;   MODE 2
  69.         INT  10H
  70. SCREEN_MODE_OK:
  71.  
  72. ;SC_TITLE
  73.        MOV AH,2         ;CALL TO SET CURSOR POSITION
  74.        MOV  DX,0112H    ;CURSOR POSITION
  75.        MOV  BH,0
  76.        INT  10H
  77.        MOV  BX,OFFSET SC_TITLE  ;PUT SC_TITLE ADDRESS IN BX
  78.        MOV  OFFSET_VALUE,BX     ;PUT ADDRESS IN VARIABLE
  79.        CALL DISPLAY  
  80.  
  81. ;TYPE_NUM
  82.       MOV  AH,2
  83.       MOV  DX,0210H     ;CURSOR POSITION
  84.       MOV  BH,0
  85.       INT  10H
  86.       MOV  BX,OFFSET TYPE_NUM
  87.       MOV  OFFSET_VALUE,BX      ;PUT ADDRESS IN VARIABLE
  88.       CALL DISPLAY
  89.  
  90. ;INPUT_NUM
  91.        MOV  AH,2
  92.        MOV  DX,0310H    ;CURSOR POSITION
  93.        MOV  BH,0
  94.        INT  10H
  95.        MOV  BX,OFFSET INPUT_NUM
  96.        MOV  OFFSET_VALUE,BX
  97.        CALL DISPLAY
  98.  
  99. ;COL_HEADER
  100.        MOV  AH,2        ;CALL TO SET CURSOR POSITION
  101.        MOV  DX,0510H    ;CURSOR POSITION
  102.        MOV  BH,0
  103.        INT  10H
  104.        MOV  BX, OFFSET COL_HEADER
  105.        MOV  OFFSET_VALUE,BX        ;PUT ADDRESS IN VARIABLE
  106.        CALL DISPLAY
  107.  
  108. ;UNDERLINE
  109.        MOV  AH,2
  110.        MOV  DX,0610H     ;CURSOR POSITION
  111.        MOV  BH,0
  112.        INT  10H
  113.        MOV  BX,OFFSET UNDERLINE
  114.        MOV  OFFSET_VALUE,BX
  115.        CALL DISPLAY
  116.  
  117. ;POSITION CURSOR FOR KEYBOARD INPUT
  118. INPUT:
  119. ;CLEAR_INPUT_AREA
  120.        MOV  AH,2
  121.        MOV  DH,3
  122.        MOV  DL,25H
  123.        MOV  BH,0
  124.        INT  10H
  125.       
  126.       MOV   BH,0
  127.        MOV  CX,30    ;blank 30 spaces       
  128.        MOV  AH,10    ;WRITE CHAR AT CURSOR LOCATION
  129.        MOV  AL,' '   ;BLANK
  130.        INT  10H
  131.  
  132. ;clear test_string
  133.        LEA  SI,TEST_STRING
  134.        mov   cx,10             ;TEST STRING IS 10 CHAR LONG
  135. next_char:
  136.         MOV  BYTE PTR [SI],' '
  137.         inc  SI
  138.         dec  cx
  139.         cmp  cx,0
  140.         JA  next_char
  141.  
  142. ;SCROLL PART OF SCREEN DOWN TOO BET READY FOR NEXT INPUT
  143.        MOV  AH,7     ;SCROLL ACTIVE PAGE DOWN
  144.        MOV  AL,1     ;NUMBER OF LINES
  145.        MOV  CH,7     ;UPPER LINE TO SCROLL
  146.        MOV  CL,0     ;LEFT COLUMN OF SCROLL
  147.        MOV  DH,23    ;LOWER LINE OF SCROLL
  148.        MOV  DL,79    ;RIGHT COLUMN OF SCROLL
  149.        MOV  BH,0FH   ;ATTRIBUTE OF BLANK LINE
  150.        INT  10H      ;DO IT
  151.  
  152.        MOV  INPUT_LARGE,0   ;SET TO ZERO AT START-UNDER 65384
  153.        MOV  INPUT_STATUS,0  ;SET TO ZERO AT START-NUMBERS
  154.        MOV  AH,2
  155.        MOV  DX,0325H      ;CURSOR POSITION
  156.        MOV  BH,0
  157.        INT  10H
  158.  
  159.        CALL READ_KEYS
  160.  
  161. ;PUT THE TEST_NUMBER UNDER THE TEST NUMBER COLUMN HEADING
  162.        MOV  AH,2
  163.        MOV  DX,0711H        ;CURSOR POSITION
  164.        MOV  BH,0
  165.        INT  10H
  166.        MOV  BX,OFFSET TEST_STRING
  167.        MOV  CX,10
  168. PUT_TEST_NUMBER:
  169.        MOV  AL,[BX]         ;PUT STRING CHAR IN AX
  170.        MOV  AH,14           ;FUNCTION CODE FOR WRITE AND ADVANCE CURSOR
  171.        INT  10H
  172.        INC  BX              ;NEXT CHARACTER IN STRING
  173.        LOOP PUT_TEST_NUMBER ;PUT ALL OF STRING + BLANKS
  174.  
  175.  
  176.  
  177. ;PREPAIR TO CALL ASCII_BIN ROUTINE
  178. ;PUT STARTING ADDRESS OF STRING IN BX
  179. ;PUT CHARACTER COUNT IN CX
  180.        MOV  BX,OFFSET TEST_STRING
  181.        MOV  CX,CHAR_COUNT
  182.  
  183.        CALL ASCII_BIN       ;CONVERT STRING TO NUMBER
  184.  
  185.  
  186.       JC  CARRY_SET        ;GO CHECK WHY
  187.       MOV TEST_NUMBER,AX   ;SAVE TEST NUMBER
  188.       MOV  DEC_POINT,DX    ;SAVE DECIMAL POINT
  189.       CMP AX,0             ;CHECK FOR NEGATIVE
  190.       JGE  NUM_OK          ;NUMBER IS GOOD-GO DO SQ ROOT  
  191.       MOV AH,2
  192.       MOV  DX,0730H        ;CURSOR POSITION
  193.       INT  10H
  194.       MOV  BX,OFFSET ERR_MSG3   ;NEGITIVE NUMBER
  195.       MOV  OFFSET_VALUE,BX
  196.       CALL DISPLAY
  197.  
  198.       JMP  INPUT            ;NEXT KEYBOARD INPUT
  199.  
  200. BAD_CHAR:
  201.       MOV  AH,2
  202.       MOV  DX,0730H         ;CURSOR POSITION
  203.       MOV  BH,0
  204.       INT  10H
  205.       MOV  BX,OFFSET ERR_MSG1  ;NOT VALID INPUT
  206.       MOV  OFFSET_VALUE,BX
  207.       CALL DISPLAY
  208.  
  209.       JMP  INPUT           ;GO GET NEXT KEYBOARD INPUT
  210.  
  211. CARRY_SET:
  212.       cmp  di,0ffh          ;check for bad character
  213.       jne  bad_char
  214.  
  215.        MOV  AH,2
  216.        MOV  DX,0730H        ;CURSOR POSITION
  217.        MOV  BH,0
  218.        INT  10H
  219.        MOV  BX,OFFSET ERR_MSG2
  220.        MOV  OFFSET_VALUE,BX
  221.        CALL DISPLAY
  222.  
  223.        JMP  INPUT           ;NOT VALID, GO GET NEW INPUT
  224.  
  225. NUM_OK:
  226.  
  227. ;ADJUST NUMBER FOR SQUART ROOT ROUTING BY MAKING NUMBER AS LARGE AS 
  228. ;POSSIBLE, BUT LESS THEN 32768, BY MULTIPLYING BY 10 AND CHANGINE
  229. ;DECIMAL POINT TO MATCH.                                                       
  230. ; CALL DEC_ADJ  WITH AX = NUMBER - 16 BIT SIGNED                    
  231. ;                    CX = NUMBER OF CHARACTERS TO RIGHT OF DECIMAL POINT
  232. ;RETURN WITH AX = NUMBER AND   CX = NUMBER OF CHARACTERS TO RIGHT
  233. ;OF DECIMAL POINT THAT TOGETHER = OLD NUMBER
  234. ; NOTE CX WILL BE A EVEN NUMBER
  235.    
  236.  
  237.        MOV AX,TEST_NUMBER
  238.        MOV CX,DEC_POINT
  239.        CALL DEC_ADJ     
  240.   
  241.        MOV  TEST_NUMBER,AX
  242.       
  243. ;NOW READY TO CALCULATE SQUARE ROOT.  AX IS TO CONTAIN THE TEST
  244. ;NUMBER WHEN THE SQ_ROOT ROUTINE IS CALLED AND AX WILL CONTAIN
  245. ;THE CALCULATED SQ ROOT ON RET.
  246.  
  247.         MOV AX,CX         ;PUT DEC POINT IN AX FOR DIVIDE
  248.         CWD
  249.         MOV BX,2
  250.         DIV BX
  251.         MOV  DEC_POINT,AX  ;STORE SQ ROOT OF DEC POINT
  252.  
  253.  
  254.  
  255.        MOV  AX,TEST_NUMBER    ;PUT NUMBER IN AX
  256.        CALL SQ_ROOT
  257.        MOV  SQ_ROOT_VALUE,AX  ;SAVE THE CALCULATED SQ ROOT VALUE
  258.  
  259.  
  260. ;CONVERT THE SQ_ROOT VALUE TO ASCII STRING AND PUT UNDER THE
  261. ;SQ ROOT HEADING                            
  262.  
  263. ;CONVERT THE NUMBER TO A ASCII STRING
  264.  
  265.        MOV  BX,OFFSET SQ_ROOT_STRING      ;PLACE TO PUT RESULT
  266.        CALL BIN_ASCII
  267.  
  268. ;ON RETURN BX HOLDS ADDRESS OF THE STRING AND CX THE COUNT
  269.  
  270. ;POSITION DECIMAL POINT IN SQ ROOT STRING
  271. ; CALL   PUT_DEC  WITH
  272. ;    AX = 10  SIZE OF STRING 
  273. ;    BX = OFFSET OF ASCII STRING
  274. ;    CX = NUMBER OF CHARACTERS IN STRING
  275. ;    DX = NUMBER OF CHARACTERS TO RIGHT OF DECIMAL
  276. ;RETURN IS WITH DECIMAL IN STRING AT BX
  277.  
  278.        MOV  AX,10
  279.        MOV  DX,DEC_POINT
  280.        CALL PUT_DEC
  281.  
  282. ;SQ_ROOT_STRING NOW CONTAINS THE ANSWER READY FOR DISPLAY
  283.  
  284.        MOV  AH,2
  285.        MOV  DX,0728H       ;CURSOR POSITION
  286.        MOV  BH,0
  287.        INT  10H
  288.  
  289.        MOV  BX,OFFSET SQ_ROOT_STRING
  290.        MOV  OFFSET_VALUE,BX
  291.        CALL DISPLAY
  292.  
  293.        JMP INPUT            ;READY FOR AN OTHER KEYBOARD INPUT
  294.  
  295. START ENDP
  296. ;------------------------------------------
  297. CLEAR_THE_SCREEN  PROC NEAR
  298.        PUSH AX
  299.        PUSH BX
  300.        PUSH CX
  301.        PUSH DX
  302.  
  303.        STI             ;ENABLE INTERRUPTS
  304.        MOV  AH,0       ;SELECT 80X25, B/W, ALPHANUMERIC
  305.        INT  10H  
  306.        MOV  AH,6       ;CLEAR THE SCREEN WITH THE SCROLL
  307.        MOV  AL,0       ;   UP OPTION
  308.        MOV  CX,0                                       
  309.        MOV  DH,24                       
  310.        MOV  DL,79                                      
  311.        MOV  BH,7                                           
  312.        INT  10H  
  313.             
  314.        POP DX
  315.        POP CX
  316.        POP BX
  317.        POP AX
  318.        RET             ;RETURN TO CALLER
  319. CLEAR_THE_SCREEN ENDP
  320. ;------------------------------------------
  321. DISPLAY PROC NEAR
  322. ;GET THE CHARACTER COUNT
  323.        MOV  CHAR_COUNT,0      ;SET TO 0 FOR THIS STRING
  324.        MOV  BX,OFFSET_VALUE   ;GET OFFSET OF STRING IN BX
  325.        XOR  AX,AX
  326. LOOP_COUNT:
  327.        MOV  AL,[BX]    ;PUT STRING CHAR IN AL
  328.        CMP  AL,END_SYM  ;IS THIS LAST SYMBOL IN STRING?
  329.        JE   DISP1      
  330.        INC  BX             ;ADDRESS OF NEXT CHARACTER IN STRING
  331.        ADD  CHAR_COUNT,1   ;COUNT OF CHARACTERS IN STRING
  332.        JMP  LOOP_COUNT     ;DO UNTIL END_SYM ENCOUNTERED
  333.  
  334. ;PUT THE STRING ON THE SCREEN
  335. DISP1:  MOV  BX,OFFSET_VALUE     ;GET OFFSET OF STRING IN BX
  336.         MOV  CX,CHAR_COUNT   ;NO. OF CHARACTERS IN STRING
  337. DISP2:  MOV  AL,[BX]         ;GET NEXT CHARACTER 
  338.         CALL DISPCHAR
  339.         INC  BX              ;POINT TO NEXT CHARACTER
  340.         LOOP DISP2           ;DO IT CX TIMES
  341.  
  342.         RET
  343. DISPLAY ENDP
  344. ;---------------------------------------------------------
  345. DISPCHAR PROC NEAR
  346.         PUSH BX
  347.         MOV  BX,0     ;SELECT DISPLAY PAGE 0
  348.         MOV  AH,14    ;FUNCTION CODE FOR 'WRITE'
  349.         INT  10H      ;CALL BIOS
  350.         POP  BX
  351.         RET
  352. DISPCHAR ENDP
  353. ;--------------------------------------------------------
  354. READ_KEYS PROC NEAR
  355.        PUSH AX
  356.        PUSH DI
  357.        STI            ;ENABLE INTERRUPTS
  358.        MOV  AH,15     ;READ DISPLAY PAGE NUMBER INTO BX
  359.        INT  10H
  360.        MOV  DI,0      ;SET KEY COUNT TO ZERO
  361.        MOV  CX,5      ;UP TO 5  KEY STROKES
  362. GET_KEY:
  363.        MOV  AH,0      ;READ NEXT KEY
  364.        
  365.        INT 16H
  366.        CMP  AL,ESC    ;IS IT ESC?
  367.        JE   GO_EXIT   ;RETURN TO DOS IN TWO STEPS(JE SHORT-LABEL ONLY)
  368.        CMP  AL,0DH    ;IS IT A CARRIAGE RETURN?
  369.        JE   SAVE_CNT  ;IF IT WAS A CARRIAGE RETURN THEN GO TO NEXT STEP
  370.        MOV  TEST_STRING[DI],AL    ;STORE THE KEY INPUT
  371.        INC  DI                    ;INCREASE THE KEY COUNT
  372.        MOV  AH,14                 ;DISPLAY THE CHARACTER
  373.        PUSH DI                     ;SAVE REGISTER
  374.        INT  10H
  375.        POP  DI
  376.        LOOP GET_KEY               ;GO GET NEXT KEY
  377. SAVE_CNT:
  378.        MOV  CX,DI                 ;PUT FINAL KEY COUNT IN CX
  379.        MOV  CHAR_COUNT,CX         ;STORE NO OF CHARS IN STRING
  380.        LEA  BX,TEST_STRING        ;BUFFER ADDRESS IN BX
  381.        POP DI
  382.        POP AX
  383.        RET               ;RETURN TO CALLER
  384. GO_EXIT:
  385.        POP DI
  386.        POP AX
  387.        POP AX
  388.        JMP EXIT          ;RETURN TO DOS
  389.  
  390. READ_KEYS ENDP
  391. ;----------------------------------------------------------
  392. ;-----------------------------------------------------------------
  393. ;
  394. ;-------------------------------------------------------------
  395. ;----------------------------------------------------------------
  396. ;INTEGER SQUARE ROOT
  397. ;  CALL WITH    AX = ARGUMENT
  398. ;  RETURN       AX = SQUARE ROOT
  399. ;
  400. SQ_ROOT PROC
  401. SQRT:
  402.         PUSH BX
  403.         PUSH CX
  404.         PUSH DX
  405.         MOV  DX,AX     ;ARGUMENT INTO DX
  406.         MOV  CX,8      ;NUMBER OF ITERATIONS
  407.         XOR  BX,BX     ;CLEAR THE REMAINDER
  408.         MOV  AX,BX     ;CLEAR TRIAL VALUE AND FINAL RESULT STORE
  409.  
  410. SQRT1:
  411.         SHL  BX,1      ;DOUBLE PARTIAL RESULT
  412.         INC  BX        ;GUESS NEXT BIT IS A 1
  413.         SHL  DX,1      ;FETCH 2 NEW BITS
  414.         RCL  AX,1      ; FROM ARGUMENT
  415.         SHL  DX,1
  416.         RCL  AX,1
  417.         SUB  AX,BX     ;DO A TRIAL SUBTRACTION
  418.         JNC  SQRT2     ;GUESS WAS RIGHT
  419.                        ; APPEND A 1 BIT
  420.         ADD  AX,BX     ;GUESS WAS WRONG, PUT IT BACK
  421.         DEC  BX        ;AND CLEAN UP FOR NEXT PASS
  422.         LOOP SQRT1
  423.         JMP  SQRT3     ;GO SCALE RESULT
  424. SQRT2: 
  425.         INC  BX        ;CONVERT xxxx01 to
  426.                        ;xxxx10, i.e. append a 1 bit
  427.         loop sqrt1
  428. SQRT3:
  429.         SAR  BX,1      ;DIVIDE BY 2 TO GET
  430.                        ;ACTUAL SQUARE ROOT
  431.         MOV  AX,BX     ;RETURN RESULT IN AX
  432.  
  433.         POP  DX
  434.         POP  CX
  435.         POP  BX
  436.         
  437.         RET            ;RETURN TO CALLER
  438.  
  439. SQ_ROOT ENDP
  440. ;--------------------------------------------------------------------
  441. EXIT_TO_DOS PROC FAR
  442. EXIT:  RET            ;RETURN TO DOS
  443. EXIT_TO_DOS ENDP
  444. ;----------------------------------------------------------
  445.  
  446. CODE   ENDS
  447.        END   START
  448.